package com.ddw.wotcg.server.controllers;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;

import com.ddw.wotcg.server.utils.FieldValidation;
import com.ddw.wotcg.server.utils.Hasher;
import com.ddw.wotcg.server.utils.RequestHelper;
import com.ddw.wotcg.server.utils.TemplateHelper;
import com.ddw.wotcg.server.utils.User;
import com.ddw.wotcg.server.utils.UserHelper;

@SuppressWarnings("serial")
public class SignInController extends ControllerBase {
	
	public void complete() throws IOException, ServletException {
		final Map<String, Object> root = new HashMap<String, Object>();
		final Map<String, String> cookies = RequestHelper
				.parseCookies(this.request);
		final UUID session = RequestHelper.getSession(cookies);
		final User user = UserHelper.bySession(session);
		
		// If user is logged in then redirect them
		if (user != null) {
			this.response.sendRedirect("/home");
			return;
		}
		
		TemplateHelper.appendPageData(root, "Sign In Complete");
		TemplateHelper.appendUserData(root, user);
		
		TemplateHelper.callTemplate(this.config, this.response,
				"/signin/complete.ftl", root);
	}
	
	public void index() throws IOException, ServletException {
		final Map<String, Object> root = new HashMap<String, Object>();
		final Map<String, String> cookies = RequestHelper
				.parseCookies(this.request);
		final UUID session = RequestHelper.getSession(cookies);
		final User user = UserHelper.bySession(session);
		
		// If user is logged in then redirect them
		if (user != null) {
			this.response.sendRedirect("/home");
			return;
		}
		
		TemplateHelper.appendPageData(root, "Sign In");
		TemplateHelper.appendUserData(root, user);
		
		// Populate defaults
		root.put("email", "");
		root.put("emailInvalid", null);
		root.put("password", "");
		root.put("passwordInvalid", null);
		
		// If its a post request then try to login
		if ("POST".equals(this.request.getMethod())) {
			if (signIn(root)) {
				return;
			}
		}
		
		TemplateHelper.callTemplate(this.config, this.response,
				"/signin/index.ftl", root);
	}
	
	/**
	 * Attempt to validate a user and sign them in
	 * 
	 * @param root
	 *            the root map to append to for the template
	 * @return a flag indicating if the sign in completed
	 */
	private boolean signIn(Map<String, Object> root) throws IOException {
		// Get the parameters
		final String email = this.request.getParameter("email");
		String password = this.request.getParameter("password");
		
		// Post back variables for page
		root.put("email", email);
		root.put("password", password);
		
		// Check email
		if (FieldValidation.validEmail(email) == false) {
			root.put("emailInvalid",
					"Please enter a valid email address e.g. someone@mail.com");
			return false;
		}
		
		// Check password
		if (FieldValidation.validPassword(password) == false) {
			root.put(
					"passwordInvalid",
					"Please enter a valid password, at least six characters, must include one letter and one number");
			return false;
		}
		
		// Find via email
		final User user = UserHelper.byEmail(email);
		
		// If user doesn't exist then flag an error
		if (user == null) {
			root.put("emailInvalid",
					"The email address or password was incorrect, try again");
			return false;
		}
		
		// We are now safe to create the user record, hash the password
		password = Hasher.hash(password);
		
		// Check the users password is the same
		if (password.equals(user.password) == false) {
			root.put("emailInvalid",
					"The email address or password was incorrect, try again");
			return false;
		}
		
		// We have a valid user and now need to create a session
		user.session = UUID.randomUUID();
		user.sessionCreated = new Date();
		UserHelper.save(user);
		
		// Create a session cookie to track the user
		this.response.addCookie(new Cookie(TemplateHelper.SESSION_COOKIE,
				user.session.toString()));
		this.response.sendRedirect("/signin/complete");
		return true;
	}
	
}
